package testing;

import static org.junit.Assert.*;
import hypeerweb.HyPeerWeb;


import org.junit.Test;

import hypeerweb.*;
import hypeerweb.node.*;
import hypeerweb.visitor.*;

public class SendVisitorTest {
	/*
	@Test
	public void test() {
		HyPeerWeb hypeerweb = HyPeerWeb.getSingleton();
		hypeerweb.clear();
		
		Node n0 = new Node(0);
		Node n1 = new Node(1);
		Node n2 = new Node(2);
		Node n3 = new Node(3);
		Node n4 = new Node(4);
		Node n5 = new Node(5);
		Node n6 = new Node(6);
		Node n7 = new Node(7);
		Node n8 = new Node(8);
		Node n9 = new Node(9);
		
		hypeerweb.addToHyPeerWeb(n0, null);
		
		n0.addToHyPeerWeb(n1);
		n0.addToHyPeerWeb(n2);
		n0.addToHyPeerWeb(n3);
		n0.addToHyPeerWeb(n4);
		n0.addToHyPeerWeb(n5);
		n0.addToHyPeerWeb(n6);
		n0.addToHyPeerWeb(n7);
		n0.addToHyPeerWeb(n8);
		
		//TEST Send from 7 to 0
		Parameters para1 = SendTest.createInitialParameters(0);
		String message = "SEND";
		String str = "FINAL";
		int height = n0.getWebId().getHeight();
		para1.set(message, str);
		n7.accept(new SendTest(), para1);
		assertTrue(n0.getContents().containsKey(message));

		assertTrue(n0.getContents().get(message) == str);
		
		assertTrue((Integer) n0.getContents().get("JUMP") <= height);
		
		assertFalse(n1.getContents().containsKey(message));
		assertFalse(n2.getContents().containsKey(message));
		assertFalse(n3.getContents().containsKey(message));
		assertFalse(n4.getContents().containsKey(message));
		assertFalse(n5.getContents().containsKey(message));
		assertFalse(n6.getContents().containsKey(message));
		assertFalse(n7.getContents().containsKey(message));
		assertFalse(n8.getContents().containsKey(message));
		assertFalse(n9.getContents().containsKey(message));
		
		
		//TEST Send again to 0
		Parameters para2 = SendTest.createInitialParameters(0);
		
		para2.set(message, str);
		
		n5.accept(new SendTest(), para2);		
		assertTrue(n0.getContents().get(message) == str);
		
		//TEST Send different message
		Parameters para3 = SendTest.createInitialParameters(5);
		String msg = message;
		
		para3.set(msg, str);
		
		n0.accept(new SendTest(), para3);
		
		assertTrue(n5.getContents().containsKey(msg));

		assertTrue(n5.getContents().get(msg) == str);
		
		assertTrue((Integer) n5.getContents().get("JUMP") <= height);
		
		assertFalse(n0.getContents().containsKey(msg));
		assertFalse(n1.getContents().containsKey(msg));
		assertFalse(n2.getContents().containsKey(msg));
		assertFalse(n3.getContents().containsKey(msg));
		assertFalse(n4.getContents().containsKey(msg));
		assertFalse(n6.getContents().containsKey(msg));
		assertFalse(n7.getContents().containsKey(msg));
		assertFalse(n8.getContents().containsKey(msg));
		assertFalse(n9.getContents().containsKey(msg));
	}
*/
	
	@Test
	public void partitionTest()
	{
		//Equivalence partitioning
		Parameters para1 = SendTest.createInitialParameters(20);
		Parameters paraFake = new Parameters();
		SendTest test = new SendTest();
		
		HyPeerWeb web = createHyPeerWebWith(10);
		Node node = web.getNode(0);
		
		
		//test invalid
//		test.visit(null, para1);
//		test.visit(node, null);
//		test.visit(node, paraFake);
//		test.visit(node, para1);
		
		// test valid partitions

		//complete hypercube
		testSize(8);
		
		//incomplete hypercube
		testSize(5);
		
		//large hypercube
		testSize(100);
		
		//small hypercube
		testSize(1);

	}
	
	@Test
	public void borderTest()
	{
		//border complete hypercube
		testSize(7);
		testSize(8);
		testSize(9);
		
		//smaller values
		testSize(2);
		testSize(3);
		
		//test larger complete cube
		testSize(128);
	}
	
	private void testSize(int size)
	{
		String KEY = "SEND";
		String MSG = "FINAL";
		SendTest send = new SendTest();
		
		//send from every node to every node
		for(int i =0; i < size; i++)
		{	
			for(int j = 0; j < size; j++)
			{
				HyPeerWeb web = createHyPeerWebWith(size);
				
				Node from = web.getNode(j);
				
				Parameters para1 = SendTest.createInitialParameters(i);
				para1.set(KEY, MSG);
				
				from.accept(send, para1);
				
				for(int x = 0; x < size; x ++)
				{
					Node target = web.getNode(x);
					Contents contents = target.getContents();
					if(x == i)
					{
						assertTrue(contents.get(KEY).equals(MSG));
						
						Node largest = web.getNode(web.size()-1);
						
						int height = largest.getWebId().getHeight();
						
						int jumps = (Integer) contents.get(send.JUMP);
						assertTrue(jumps <= height);
						assertTrue(contents.get(send.INTER) == null);
					}
					else
					{
						assertTrue(contents.get(KEY) == null);
					}
				}
			}
		}
	}
	
	private HyPeerWeb createHyPeerWebWith(int numberOfNodes) {
		HyPeerWeb hypeerweb = HyPeerWeb.getSingleton();
		hypeerweb.clear();
		Node node0 = new Node(0);
		hypeerweb.addToHyPeerWeb(node0, null);

		for (int i = 1; i < numberOfNodes; i++) {
			Node node = new Node(0);
			node0.addToHyPeerWeb(node);
		}
		
		return hypeerweb;
	}
	
}
